package cate.game.activity.luckyblindbox;

import cate.common.table.activity.luckyblindbox.row.KoiRewardPoolRow;
import cate.common.table.activity.luckyblindbox.row.LuckyBlindBoxBaseRow;
import cate.common.table.activity.luckyblindbox.row.RandomRewardPoolRow;
import cate.common.table.d.GDFunc;
import cate.common.table.pay.PayItemRow;
import cate.common.util.GameResult;
import cate.common.util.random.RWList;
import cate.game.activity.base.core.RoleActivitySingle;
import cate.game.activity.luckyblindbox.msg.LuckyBlindBoxInfoResp;
import cate.game.res.MixRes;
import cate.game.role.Role;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteField;

import java.beans.Transient;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class LuckyBlindBoxActivity extends RoleActivitySingle {
    @NoteField("随出来的奖励,key为位置，value为配置id")
    public Map<Integer, Integer> rewards;
    @NoteField("随出来的锦鲤奖,key为位置，value为配置id")
    public Map<Integer, Integer> koiRewards;
    @NoteField("当日已购买次数")
    public int buyTimes;
    @NoteField("历史已购买次数")
    public int totalBuyTimes;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (rewards == null) {
            rewards = new HashMap<>();
        }
        if (koiRewards == null) {
            koiRewards = new HashMap<>();
        }
    }


    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        this.buyTimes = 0;
        rewards.clear();
        koiRewards.clear();
        if (!silence) {
            noticeUpdate();
        }
    }

    public GameResult<LuckyBlindBoxActivity> drawRewards() {
        GameResult<LuckyBlindBoxActivity> r = new GameResult<>();
        r.data = this;
        LuckyBlindBoxBaseRow baseRow = getBaseRow();
        if (baseRow == null) {
            return r.fail("活动配置不存在");
        }
        if (!rewards.isEmpty()) {
            return r.fail("已抽取过奖励");
        }
        drawExe();
        return r;
    }

    public void drawExe() {
        RWList<RandomRewardPoolRow> r = new RWList<>();
        LuckyBlindBoxBaseRow baseRow = getBaseRow();
        for (int i = 0; i < baseRow.randomNum; i++) {
            List<RandomRewardPoolRow> list = getRandomListByPos(i + 1);
            r.addAndSetup(list);
            RandomRewardPoolRow row = r.get();
            rewards.put(i + 1, row.id);
            r.clear();
        }
        if (Math.random() * 10000 < baseRow.koiRate) {
            return;
        }
        RWList<KoiRewardPoolRow> kr = new RWList<>();
        for (int i = 0; i < baseRow.koiNum; i++) {
            List<KoiRewardPoolRow> list = getKoiListByPos(i + 1);
            if (list == null || list.isEmpty()) {
                continue;
            }
            kr.addAndSetup(list);
            KoiRewardPoolRow row = kr.get();
            koiRewards.put(i + 1, row.id);
            kr.clear();
        }
    }

    @Override
    public GameResult<Void> allowPay(PayItemRow pir) {
        GameResult<Void> r = new GameResult<>();
        LuckyBlindBoxBaseRow baseRow = getBaseRow();
        if (baseRow == null) {
            return r.fail("活动未开启");
        }
        if (rewards.isEmpty()) {
            return r.fail("奖励为空");
        }
        if (buyTimes >= baseRow.buyLimit) {
            return r.fail("今日奖励已购买");
        }
        return r;
    }

    @Override
    public void onPaySuccess(PayItemRow pir) {
        if (rewards.isEmpty()) {
            return;
        }
        MixRes reward = rewards.values().stream().map(tid -> new MixRes(getRandomRow(tid).rewardStr)).reduce(new MixRes(), MixRes::addList);
        if (!koiRewards.isEmpty()) {
            MixRes reduce = koiRewards.values().stream().map(tid -> new MixRes(getKoiRow(tid).rewardStr)).reduce(new MixRes(), MixRes::addList);
            reward.addList(reduce);
        }
        reward.add(role, true, GDFunc.LUCKY_BLIND_BOX);
        role.getGame().notice.dialogReward(role, reward);
//        rewards.clear();
//        koiRewards.clear();
        buyTimes++;
//        totalBuyTimes++;
        noticeUpdate();
    }

    @Override
    public void onRoleOpen() {

    }

    @Override
    public void onRoleEnd() {
        this.buyTimes = 0;
        rewards.clear();
        koiRewards.clear();
        this.totalBuyTimes = 0;
    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    public void noticeUpdate() {
        role.sendNow(new LuckyBlindBoxInfoResp(this));
    }

    @Override
    public void excelCheck() {

    }

    @JsonIgnore
    @Transient
    private LuckyBlindBoxBaseRow getBaseRow() {
        return role.getGame().table.blindBox.base.get(configTid());
    }

    private RandomRewardPoolRow getRandomRow(int tid) {
        return role.getGame().table.blindBox.random.get(tid);
    }

    private KoiRewardPoolRow getKoiRow(int tid) {
        return role.getGame().table.blindBox.koi.get(tid);
    }

    @JsonIgnore
    @Transient
    private List<RandomRewardPoolRow> getRandomListByPos(int pos) {
        if (getBaseRow() == null) {
            return null;
        }
        List<RandomRewardPoolRow> poolRows = role.getGame().table.blindBox.random.groupMap.get(pos);
        return poolRows.stream().filter(row -> row.group == getBaseRow().randomGroup).collect(Collectors.toList());
    }

    @JsonIgnore
    @Transient
    private List<KoiRewardPoolRow> getKoiListByPos(int pos) {
        if (getBaseRow() == null) {
            return null;
        }
        List<KoiRewardPoolRow> poolRows = role.getGame().table.blindBox.koi.groupMap.get(pos);
        return poolRows.stream().filter(row -> row.group == getBaseRow().koiGroup).collect(Collectors.toList());
    }
}
